package com.didiglobal.turbo.demo.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.context.request.async.DeferredResult;
import reactor.netty.http.client.HttpClient;

import java.util.function.Function;

/**
 * @author zhanglu
 * @project dev-zhanglu-20230130
 * @description 响应式netty http工具类
 *  - 参考：https://projectreactor.io/docs/netty/release/reference/index.html#_consuming_data_4
 * @date 2023/3/27 16:07
 */
@Slf4j
public class ReactorNettyHttpUtils {

    /**
     * 同步执行请求
     * @param httpClient
     * @return
     */
    public static String syncExecute(HttpClient.ResponseReceiver httpClient){
        try {
            return httpClient.responseContent().aggregate().asString().block();
        } catch (Exception e) {
            log.error("reactor-netty-http同步请求异常", e);
            return null;
        }
    }

    /**
     * 异步执行请求
     * @param httpClient
     * @param func
     * @param <R>
     * @return
     */
    public static <R> DeferredResult<R> asyncExecute(HttpClient.ResponseReceiver httpClient, Function<String, R> func){
        try {
            DeferredResult<R> deferredResult = new DeferredResult<>();
            httpClient.responseContent().aggregate().asString()
            .doOnNext(res -> deferredResult.setResult(func.apply(res)))
            .doOnError(e -> log.error("reactor-netty-http异步请求异常", e))
            .subscribe();
            return deferredResult;
        } catch (Exception e) {
            log.error("reactor-netty-http异步请求异常", e);
            return null;
        }
    }

    public static void main(String[] args) {
        String url = "http://127.0.0.1:8201/form-template/detail/1";
        DeferredResult<String> deferredResult = asyncExecute(HttpClient.create().get().uri(url), x -> x);
        System.out.println(1);
        String res = null;
        System.out.println(2);
        while ((res = (String) deferredResult.getResult()) == null){

        }
        System.out.println(res);

        System.out.println("----------------------------------");

        res = syncExecute(HttpClient.create().get().uri(url));
        System.out.println(res);
    }

}
